/*
 * Middleware
 * Copyright (C) 2010/11
 * Riccardo Pulvirenti, Giuseppe Ravidà, Andrea Tino
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses
 */

/*!
 * File: synlogger.hpp
 */

#ifndef _SYNLOGGER_HPP_
#define _SYNLOGGER_HPP_

#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>


//-----------------------------------------------------------------------------
// Class definitions
namespace middleware {
/*! \class SynLogger
 * \brief Class for synchronized multithreaded logging.
 *
 * This class represents a log for the application. Logs are treated as files
 * and for this reason, given a multithread context, it is necessary to protect
 * them from being written and read at the same time in order to avoid data
 * inconsistances.
 */
class SynLogger {
public:
	/*!
	 * Creates a logger with a static name and static tag.
	 */
	SynLogger();
	/*!
	 * Constructor creating a logger (file) with specified name (no extension
	 * should be provided) and the specified tag.
	 * \param logname The name of the log file, no extension should be provided,
	 * it will be automatically added.
	 * \param logtag Tag for the log file. This is the string that appears inside
	 * the file at every line. It represent the entity responsible for logging.
	 */
	SynLogger(std::string logname, std::string logtag);
	/*!
	 * Copy constructor.
	 */
	SynLogger(const SynLogger& logger);
	/*!
	 * Gets the file name comprehensive of the added extension .middleware.log.
	 * \return Returns the file name.
	 */
	std::string get_log_filename() {
		return this->_log_filename;
	}
	/*!
	 * Sets the file name for the current log. No extension should be provided,
	 * it is added automatically.
	 * \param filename File name with no extension.
	 */
	void set_log_filename(const std::string& filename) {
		this->_log_filename = filename + std::string(".middleware.log");
	}
	/*!
	 * Gets the tag.
	 * \return Returns the tag.
	 */
	std::string get_log_tag() {
		return this->_log_tag;
	}
	/*!
	 * Sets the tag.
	 * \param tag The tag to assign.
	 */
	void set_log_tag(const std::string& tag) {
		this->_log_tag = tag;
	}
	/*!
	 * Destructor.
	 */
	~SynLogger();
	/*!
	 * Opens the file, if it does not esist yet the file is well created on
	 * the fly, and writes the provided line adding at the begging the tag and
	 * the timestamp. These operations are made in compliance with data consistency
	 * minding concurrency.
	 * \param logstring The line to write, do not add dates because timestamp is
	 * attached automatically.
	 */
	void Print(std::string logstring);
protected:
	/*!
	 * Opens configuration file. If file does not exist (local), then the file
	 * with logname.middleware.log, must be created and opened.
	 */
	void Open();
	/*!
	 * Closes the file
	 */
	void Close();
	/*!
	 * Lock/Unlock.
	 */
	boost::mutex _print_monitor;
	/*!
	 * Logging file tag.
	 */
	std::string _log_tag;
	/*!
	 * Logging file name. Path will be local.
	 */
	std::string _log_filename;
	/*!
	 * Logging file.
	 */
	std::ofstream _log_file;
};
}

#endif
